import * as vscode from 'vscode';
import Parser = require('tree-sitter');
import { ASTHelper } from './astHelper';
import { TextHelper } from './textHelper';
import { sendContextToLLM } from './llmAnalysisFunctions';

export interface CodeBlock {
  type: string;
  name?: string;
  content: string;
  range: vscode.Range;
  depth: number;
  description: string;
  // 新增字段
  entryCondition?: string;  // 入口条件（if/while/for/switch的条件部分）
  parameters?: string;      // 函数参数
  signature?: string;       // 完整签名（函数声明行）
}

export class ContextAnalyzer {
  private static readonly LOGICAL_BLOCK_TYPES = [
    'function_definition',
    'function_declaration', 
    'method_definition',
    'class_declaration',
    'class_definition',
    'if_statement',
    'while_statement',
    'for_statement',
    'try_statement',
    'catch_clause',
    'with_statement',
    'switch_statement',
    'case_clause',
    'block_statement',
    'compound_statement',
    'block',
    'suite',  // Python
    // C/C++ 特定的节点类型
    'function_declarator',
    'declaration',
    'expression_statement',
    'return_statement',
    'do_statement',
    'case_statement',
    'default_statement',
    'labeled_statement',
    'translation_unit',
    'preproc_include',
    'using_declaration',
    'namespace_definition'
  ];

  private static readonly CONTAINER_TYPES = [
    'function_definition',
    'function_declaration',
    'method_definition', 
    'class_declaration',
    'class_definition',
    'module',
    'function_declarator'
  ];

  static findLogicalCodeBlock(
    tree: Parser.Tree,
    position: { row: number; column: number },
    doc: vscode.TextDocument
  ): CodeBlock | null {
    
    const currentNode = ASTHelper.findNodeAtPosition(tree.rootNode, position);
    if (!currentNode) {
        return null;
    }

    // 改进的逻辑：优先查找最相关的代码块
    const relevantBlock = this.findMostRelevantBlock(currentNode);
    if (relevantBlock) {
      return this.buildCodeBlock(relevantBlock, doc);
    }

    // 如果没找到相关块，使用原来的逻辑
    const logicalBlock = this.findNearestLogicalBlock(currentNode);
    if (!logicalBlock) {
      let parent = currentNode.parent;
      while (parent) {
        if (this.isLogicalBlock(parent.type) || this.isMeaningfulBlock(parent.type)) {
          return this.buildCodeBlock(parent, doc);
        }
        parent = parent.parent;
      }
      
      const nodeToUse = this.findMeaningfulNode(currentNode, tree.rootNode);
      return nodeToUse ? this.buildCodeBlock(nodeToUse, doc) : null;
    }

    return this.buildCodeBlock(logicalBlock, doc);
  }

  // 新增：查找最相关的代码块
  private static findMostRelevantBlock(node: Parser.SyntaxNode): Parser.SyntaxNode | null {
    let current: Parser.SyntaxNode | null = node;
    let candidates: { node: Parser.SyntaxNode; priority: number }[] = [];

    // 向上遍历，收集候选节点并分配优先级
    while (current) {
      const priority = this.getBlockPriority(current.type);
      if (priority > 0) {
        candidates.push({ node: current, priority });
      }
      current = current.parent;
    }

    // 按优先级排序，优先级高的在前
    candidates.sort((a, b) => b.priority - a.priority);

    // 返回优先级最高的节点
    return candidates.length > 0 ? candidates[0].node : null;
  }

  // 新增：为不同类型的代码块分配优先级
  private static getBlockPriority(nodeType: string): number {
    // 控制结构优先级最高
    if (['if_statement', 'while_statement', 'for_statement', 'switch_statement'].includes(nodeType)) {
      return 10;
    }
    
    // 函数和类次之
    if (['function_definition', 'function_declaration', 'method_definition', 'class_definition', 'class_declaration'].includes(nodeType)) {
      return 8;
    }
    
    // try-catch 语句
    if (['try_statement', 'catch_clause'].includes(nodeType)) {
      return 7;
    }
    
    // case 语句
    if (['case_clause', 'case_statement'].includes(nodeType)) {
      return 6;
    }
    
    // 其他逻辑块
    if (this.isLogicalBlock(nodeType)) {
      return 5;
    }
    
    // 有意义的块
    if (this.isMeaningfulBlock(nodeType)) {
      return 3;
    }
    
    // 复合语句优先级较低
    if (['compound_statement', 'block_statement', 'block'].includes(nodeType)) {
      return 1;
    }
    
    return 0;
  }

  private static findMeaningfulNode(startNode: Parser.SyntaxNode, rootNode: Parser.SyntaxNode): Parser.SyntaxNode | null {
    let current: Parser.SyntaxNode | null = startNode;
    while (current) {
      if (this.isMeaningfulBlock(current.type)) {
        return current;
      }
      current = current.parent;
    }

    for (let i = 0; i < rootNode.namedChildCount; i++) {
      const child = rootNode.namedChild(i);
      if (child && this.isMeaningfulBlock(child.type)) {
        return child;
      }
    }

    return null;
  }

  private static isMeaningfulBlock(nodeType: string): boolean {
    const meaningfulTypes = [
      'function_definition',
      'function_declarator', 
      'declaration',
      'compound_statement',
      'expression_statement',
      'return_statement',
      'if_statement',
      'while_statement',
      'for_statement',
      'class_declaration',
      'class_definition',
      'preproc_include',
      'using_declaration',
      'identifier',
      'call_expression',
      'assignment_expression'
    ];
    return meaningfulTypes.includes(nodeType);
  }

  static analyzeCurrentContext(
    tree: Parser.Tree,
    position: { row: number; column: number },
    doc: vscode.TextDocument
  ): {
    currentBlock: CodeBlock | null;
    parentBlocks: CodeBlock[];
    childBlocks: CodeBlock[];
    siblings: CodeBlock[];
  } {
    
    const currentBlock = this.findLogicalCodeBlock(tree, position, doc);
    
    if (!currentBlock) {
      return {
        currentBlock: null,
        parentBlocks: [],
        childBlocks: [],
        siblings: []
      };
    }

    const currentNode = ASTHelper.findNodeAtPosition(tree.rootNode, position);
    const blockNode = currentNode ? this.findNearestLogicalBlock(currentNode) || this.findMeaningfulNode(currentNode, tree.rootNode) : null;

    const parentBlocks = blockNode ? this.findParentBlocks(blockNode, doc) : [];
    const childBlocks = blockNode ? this.findChildBlocks(blockNode, doc) : [];
    const siblings = blockNode ? this.findSiblingBlocks(blockNode, doc) : [];

    return {
      currentBlock,
      parentBlocks,
      childBlocks,
      siblings
    };
  }

  private static findNearestLogicalBlock(node: Parser.SyntaxNode): Parser.SyntaxNode | null {
    let current: Parser.SyntaxNode | null = node;

    while (current) {
      if (this.isLogicalBlock(current.type)) {
        return current;
      }
      current = current.parent;
    }

    return null;
  }

  private static findParentBlocks(node: Parser.SyntaxNode, doc: vscode.TextDocument): CodeBlock[] {
    const parents: CodeBlock[] = [];
    let current = node.parent;

    while (current) {
      if (this.isLogicalBlock(current.type) || this.isMeaningfulBlock(current.type)) {
        const block = this.buildCodeBlock(current, doc);
        if (block) {
          parents.unshift(block);
        }
      }
      current = current.parent;
    }

    return parents;
  }

  private static findChildBlocks(node: Parser.SyntaxNode, doc: vscode.TextDocument): CodeBlock[] {
    const children: CodeBlock[] = [];
    
    const findChildrenRecursively = (parentNode: Parser.SyntaxNode, depth: number = 0) => {
      if (depth > 2) return;
      
      for (let i = 0; i < parentNode.namedChildCount; i++) {
        const child = parentNode.namedChild(i);
        if (child) {
          if (this.isLogicalBlock(child.type) || this.isMeaningfulBlock(child.type)) {
            const block = this.buildCodeBlock(child, doc);
            if (block) {
              children.push(block);
            }
          }
          if (child.type === 'compound_statement' || child.type === 'block') {
            findChildrenRecursively(child, depth + 1);
          }
        }
      }
    };

    findChildrenRecursively(node);
    return children;
  }

  private static findSiblingBlocks(node: Parser.SyntaxNode, doc: vscode.TextDocument): CodeBlock[] {
    const siblings: CodeBlock[] = [];
    const parent = node.parent;

    if (!parent) return siblings;

    for (let i = 0; i < parent.namedChildCount; i++) {
      const sibling = parent.namedChild(i);
      if (sibling && sibling !== node && (this.isLogicalBlock(sibling.type) || this.isMeaningfulBlock(sibling.type))) {
        const block = this.buildCodeBlock(sibling, doc);
        if (block) {
          siblings.push(block);
        }
      }
    }

    return siblings;
  }

  private static buildCodeBlock(node: Parser.SyntaxNode, doc: vscode.TextDocument): CodeBlock | null {
    try {
      const startPos = new vscode.Position(node.startPosition.row, node.startPosition.column);
      const endPos = new vscode.Position(node.endPosition.row, node.endPosition.column);
      const range = new vscode.Range(startPos, endPos);

      const name = this.extractBlockName(node);
      const fullContent = node.text;
      const content = this.getBlockPreview(fullContent, node.type);
      const depth = this.calculateDepth(node);
      const description = this.generateBlockDescription(node.type, name, node);
      
      // 使用简化的方法提取入口条件和参数
      const entryCondition = this.extractEntryCondition(node);
      const parameters = this.extractParameters(node);
      const signature = this.extractSignature(node);

      const block: CodeBlock = {
        type: node.type,
        name,
        content,
        range,
        depth,
        description,
        entryCondition,
        parameters,
        signature
      };

      return block;
    } catch (error) {
      console.error('构建代码块信息时出错:', error);
      return null;
    }
  }

  // 简化版本：使用字符串匹配提取入口条件
  private static extractEntryCondition(node: Parser.SyntaxNode): string | undefined {
    const nodeText = node.text.trim();
    const firstLine = nodeText.split('\n')[0]?.trim();
    
    if (!firstLine) {
      return undefined;
    }

    // 使用正则表达式匹配常见的控制结构
    const patterns = [
      // if 语句: if (condition) 或 if condition:
      {
        regex: /^if\s*\(\s*([^)]+)\s*\)/i,
        extract: (match: RegExpMatchArray) => match[1]?.trim()
      },
      {
        regex: /^if\s+([^:{]+):/i, // Python 风格
        extract: (match: RegExpMatchArray) => match[1]?.trim()
      },
      
      // while 语句: while (condition) 或 while condition:
      {
        regex: /^while\s*\(\s*([^)]+)\s*\)/i,
        extract: (match: RegExpMatchArray) => match[1]?.trim()
      },
      {
        regex: /^while\s+([^:{]+):/i, // Python 风格
        extract: (match: RegExpMatchArray) => match[1]?.trim()
      },
      
      // for 语句: for (init; condition; increment) 或 for item in collection:
      {
        regex: /^for\s*\(\s*([^)]+)\s*\)/i,
        extract: (match: RegExpMatchArray) => match[1]?.trim()
      },
      {
        regex: /^for\s+([^:{]+):/i, // Python 风格
        extract: (match: RegExpMatchArray) => match[1]?.trim()
      },
      
      // switch 语句: switch (expression)
      {
        regex: /^switch\s*\(\s*([^)]+)\s*\)/i,
        extract: (match: RegExpMatchArray) => match[1]?.trim()
      },
      
      // case 语句: case value: 或 case value
      {
        regex: /^case\s+([^:]+)/i,
        extract: (match: RegExpMatchArray) => match[1]?.trim()
      },
      
      // catch 语句: catch (exception) 或 except Exception:
      {
        regex: /^catch\s*\(\s*([^)]+)\s*\)/i,
        extract: (match: RegExpMatchArray) => match[1]?.trim()
      },
      {
        regex: /^except\s+([^:]+):/i, // Python 风格
        extract: (match: RegExpMatchArray) => match[1]?.trim()
      },
      
      // do-while: do ... while (condition)
      {
        regex: /^do\s/i,
        extract: () => {
          // 对于 do-while，需要查找整个节点中的 while 条件
          const whileMatch = nodeText.match(/while\s*\(\s*([^)]+)\s*\)/i);
          return whileMatch ? whileMatch[1]?.trim() : undefined;
        }
      }
    ];

    // 尝试匹配每个模式
    for (const pattern of patterns) {
      const match = firstLine.match(pattern.regex);
      if (match) {
        const condition = pattern.extract(match);
        if (condition) {
          // 限制条件长度，避免过长
          return TextHelper.truncate(condition, 100);
        }
      }
    }

    // 如果是函数类型，不提取条件
    if (this.isFunctionLike(node.type)) {
      return undefined;
    }

    return undefined;
  }

  // 新增：提取函数参数
  private static extractParameters(node: Parser.SyntaxNode): string | undefined {
    if (!this.isFunctionLike(node.type)) {
      return undefined;
    }

    // 查找参数列表
    const paramList = this.findChildByType(node, 'parameter_list') ||
                     this.findChildByType(node, 'parameters') ||
                     this.findChildByType(node, 'formal_parameters');
    
    if (paramList) {
      let paramText = paramList.text.replace(/^\(|\)$/g, '').trim();
      // 如果参数为空，返回空字符串而不是括号
      if (!paramText) {
        return '';
      }
      return paramText;
    }

    // 对于 function_declarator，参数可能在不同位置
    if (node.type === 'function_declarator') {
      for (let i = 0; i < node.namedChildCount; i++) {
        const child = node.namedChild(i);
        if (child && child.type === 'parameter_list') {
          let paramText = child.text.replace(/^\(|\)$/g, '').trim();
          if (!paramText) {
            return '';
          }
          return paramText;
        }
      }
    }

    // 尝试从节点文本中提取参数（后备方案）
    const nodeText = node.text.trim();
    const match = nodeText.match(/\(([^)]*)\)/);
    if (match) {
      const paramText = match[1].trim();
      return paramText || '';
    }

    return undefined;
  }

  // 新增：提取函数签名（完整的声明行）
  private static extractSignature(node: Parser.SyntaxNode): string | undefined {
    if (!this.isFunctionLike(node.type)) {
      return undefined;
    }

    // 获取函数的第一行作为签名
    const firstLine = node.text.split('\n')[0]?.trim();
    if (firstLine && firstLine.length > 0) {
      return TextHelper.truncate(firstLine, 150);
    }

    return undefined;
  }

  // 新增：检查是否为函数类型
  private static isFunctionLike(nodeType: string): boolean {
    return [
      'function_definition',
      'function_declaration',
      'method_definition',
      'function_declarator'
    ].includes(nodeType);
  }

  private static extractBlockName(node: Parser.SyntaxNode): string | undefined {
    switch (node.type) {
      case 'function_definition':
      case 'function_declaration':
      case 'method_definition':
        let functionName = this.findChildByType(node, 'identifier')?.text ||
                          this.findChildByType(node, 'function_declarator')?.text;
        if (!functionName && (node.type === 'function_declaration' || node.type === 'method_definition')) {
                functionName = this.findChildByType(node, 'identifier')?.text;
            }
            return functionName;
        
      case 'function_declarator':
        return this.findChildByType(node, 'identifier')?.text;
        
      case 'class_definition':
      case 'class_declaration':
        return this.findChildByType(node, 'identifier')?.text;
        
      case 'declaration':
        const declarator = this.findChildByType(node, 'init_declarator') || 
                          this.findChildByType(node, 'declarator') ||
                          this.findChildByType(node, 'identifier');
        return declarator?.text;
        
      case 'expression_statement':
        const expr = this.findChildByType(node, 'assignment_expression') ||
                    this.findChildByType(node, 'call_expression') ||
                    this.findChildByType(node, 'identifier');
        return expr ? TextHelper.truncate(expr.text, 20) : undefined;
        
      case 'if_statement':
        return 'if';
        
      case 'while_statement':
        return 'while';
        
      case 'for_statement':
        return 'for';
        
      case 'try_statement':
        return 'try';
        
      case 'catch_clause':
        return 'catch';
        
      case 'switch_statement':
        return 'switch';
        
      case 'case_clause':
      case 'case_statement':
        const caseValue = this.findChildByType(node, 'number') || 
                         this.findChildByType(node, 'string') ||
                         this.findChildByType(node, 'identifier');
        return caseValue ? `case ${caseValue.text}` : 'case';
        
      case 'return_statement':
        return 'return';
        
      case 'using_declaration':
        return 'using';
        
      case 'preproc_include':
        return 'include';
        
      default:
        const identifier = this.findChildByType(node, 'identifier');
        return identifier ? TextHelper.truncate(identifier.text, 20) : undefined;
    }
  }

  private static findChildByType(node: Parser.SyntaxNode, type: string): Parser.SyntaxNode | null {
    const findRecursively = (parentNode: Parser.SyntaxNode, targetType: string, depth: number = 0): Parser.SyntaxNode | null => {
      if (depth > 3) return null;
      
      for (let i = 0; i < parentNode.namedChildCount; i++) {
        const child = parentNode.namedChild(i);
        if (child) {
          if (child.type === targetType) {
            return child;
          }
          const found = findRecursively(child, targetType, depth + 1);
          if (found) return found;
        }
      }
      return null;
    };

    return findRecursively(node, type);
  }

  private static getBlockPreview(content: string, blockType: string): string {
    const lines = content.split('\n');
    
    if (this.CONTAINER_TYPES.includes(blockType)) {
      const firstLine = lines[0]?.trim() || '';
      const maxPreviewLines = 3;
      
      if (lines.length <= maxPreviewLines) {
        return content;
      }
      
      const preview = lines.slice(0, maxPreviewLines).join('\n');
      return TextHelper.truncate(preview, 200) + '\n  // ...';
    } else {
      return TextHelper.truncate(content, 150);
    }
  }

  private static calculateDepth(node: Parser.SyntaxNode): number {
    let depth = 0;
    let current = node.parent;

    while (current) {
      if (this.isLogicalBlock(current.type) || this.isMeaningfulBlock(current.type)) {
        depth++;
      }
      current = current.parent;
    }

    return depth;
  }

  private static generateBlockDescription(
    type: string, 
    name: string | undefined, 
    node: Parser.SyntaxNode
  ): string {
    const nameText = name ? ` "${name}"` : '';
    
    switch (type) {
      case 'function_definition':
      case 'function_declaration':
      case 'function_declarator':
        return `函数定义${nameText}`;
        
      case 'method_definition':
        return `方法${nameText}`;
        
      case 'class_definition':
      case 'class_declaration':
        return `类${nameText}`;
        
      case 'declaration':
        return `声明${nameText}`;
        
      case 'expression_statement':
        return `表达式语句${nameText}`;
        
      case 'return_statement':
        return `返回语句${nameText}`;
        
      case 'if_statement':
        return '条件语句';
        
      case 'while_statement':
        return '循环语句 (while)';
        
      case 'for_statement':
        return '循环语句 (for)';
        
      case 'try_statement':
        return '异常处理语句';
        
      case 'catch_clause':
        return '异常捕获语句';
        
      case 'switch_statement':
        return '分支语句 (switch)';
        
      case 'case_clause':
      case 'case_statement':
        return `分支条件${nameText}`;
        
      case 'compound_statement':
        return '复合语句块';
        
      case 'block_statement':
      case 'block':
      case 'suite':
        return '代码块';
        
      case 'using_declaration':
        return `Using 声明${nameText}`;
        
      case 'preproc_include':
        return `头文件包含${nameText}`;
        
      default:
        return `${type}${nameText}`;
    }
  }

  private static isLogicalBlock(nodeType: string): boolean {
    return this.LOGICAL_BLOCK_TYPES.includes(nodeType);
  }

  // 增强的格式化输出，包含入口条件和参数信息
  static async formatContextInfo(context: {
    currentBlock: CodeBlock | null;
    parentBlocks: CodeBlock[];
    childBlocks: CodeBlock[];
    siblings: CodeBlock[];
    },
    doc: vscode.TextDocument,  // 新增参数
    position: vscode.Position  // 新增参数

    ): Promise<void> {
    console.log('\n========== 代码上下文分析 ==========');
    
    if (!context.currentBlock) {
      console.log('未找到当前代码块');
      console.log('=====================================\n');
      return;
    }

    // 显示当前代码块
    console.log('--- 当前代码块 ---');
    this.printCodeBlock(context.currentBlock);

    // 显示父级代码块（从外到内）
    if (context.parentBlocks.length > 0) {
      console.log('\n--- 父级代码块 ---');
      context.parentBlocks.forEach((block, index) => {
        const indent = '  '.repeat(index);
        let info = `${indent}↳ ${block.description} (行 ${block.range.start.line + 1})`;
        
        // 添加参数或入口条件信息
        const details = this.formatBlockDetails(block);
        if (details) {
          info += ` ${details}`;
        }
        
        console.log(info);
      });
    }

    // 显示子代码块
    if (context.childBlocks.length > 0) {
      console.log('\n--- 子代码块 ---');
      context.childBlocks.forEach((block, index) => {
        let info = `  ${index + 1}. ${block.description} (行 ${block.range.start.line + 1})`;
        
        const details = this.formatBlockDetails(block);
        if (details) {
          info += ` ${details}`;
        }
        
        console.log(info);
      });
    }

    // 显示同级代码块
    if (context.siblings.length > 0) {
      console.log('\n--- 同级代码块 ---');
      context.siblings.forEach((block, index) => {
        let info = `  ${index + 1}. ${block.description} (行 ${block.range.start.line + 1})`;
        
        const details = this.formatBlockDetails(block);
        if (details) {
          info += ` ${details}`;
        }
        
        console.log(info);
      });
    }

    console.log('=====================================\n');

    await sendContextToLLM(context, doc, position);
  }

  // 新增：格式化代码块详细信息
  private static formatBlockDetails(block: CodeBlock): string {
    const details: string[] = [];
    
    if (block.parameters !== undefined) {
      if (block.parameters === '') {
        details.push('- 参数: ()');
      } else {
        details.push(`- 参数: (${block.parameters})`);
      }
    }
    
    if (block.entryCondition) {
      details.push(`- 条件: ${block.entryCondition}`);
    }
    
    return details.join(' ');
  }

  private static printCodeBlock(block: CodeBlock): void {
    console.log(`类型: ${block.type}`);
    if (block.name) {
      console.log(`名称: ${block.name}`);
    }
    console.log(`描述: ${block.description}`);
    console.log(`位置: 行 ${block.range.start.line + 1}-${block.range.end.line + 1}`);
    console.log(`嵌套深度: ${block.depth}`);
    
    // 新增：显示入口条件和参数
    if (block.signature) {
      console.log(`函数签名: ${block.signature}`);
    }
    if (block.parameters !== undefined) {
      if (block.parameters === '') {
        console.log(`参数: ()`);
      } else {
        console.log(`参数: (${block.parameters})`);
      }
    }
    if (block.entryCondition) {
      console.log(`入口条件: ${block.entryCondition}`);
    }
    
    console.log('代码内容:');
    console.log(block.content);
  }
}